<script setup lang="tsx">
import { AddIcon, Delete1Icon } from 'tdesign-icons-vue-next';
import { Dropdown, Link, MessagePlugin, Space } from 'tdesign-vue-next';
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';

import { add, Delete, edit, getInfo, getList, menuTreeselect, roleMenuTreeselect } from '@/api/system/role';
import { formGroup } from '@/components/formDialog/FormDialog';
import FormDialogGroup from '@/components/formDialog/FormDialogGroup.vue';
import MyTable from '@/components/myTable/index.vue';
import OperatingBox from '@/components/operatingBox/index.vue';
import QueryBox from '@/components/queryBox/index.vue';

const { t } = useI18n();

const data = ref([]);
const columns = [
  {
    colKey: 'row-select',
    type: 'multiple' as const,
    width: 50,
  },
  {
    title: '角色编号',
    colKey: 'roleId',
  },
  {
    title: '角色名称',
    colKey: 'roleName',
  },
  {
    title: '权限字符',
    colKey: 'roleKey',
  },
  {
    title: '显示顺序',
    colKey: 'roleSort',
  },
  {
    title: '状态',
    colKey: 'status',
  },
  {
    title: '创建时间',
    colKey: 'createTime',
  },
  {
    title: '操作',
    colKey: 'op',
  },
];

const pagination = ref({
  defaultCurrent: 1,
  defaultPageSize: 10,
  total: 0,
});

const render = () => (
  <>
    <OperatingBox>
      <t-button icon={() => <AddIcon />} onClick={() => unAdd()}>
        新增
      </t-button>
      <t-button theme="danger" icon={() => <Delete1Icon />} onClick={() => deleteClickOp(deleteId.value, true)}>
        批量删除
      </t-button>
    </OperatingBox>
    <QueryBox></QueryBox>
    <MyTable
      columns={columns}
      data={data.value}
      v-model:pagination={pagination.value}
      v-model:selectedRowKeys={deleteId.value}
      rowKey="roleId"
      onUnGetList={unGetList}
    >
      {{
        status: (slotProps: any) => (
          <t-tag theme={slotProps.row.status == 0 ? 'primary' : 'danger'} variant="light">
            {slotProps.row.status == 0 ? '正常' : '停用'}
          </t-tag>
        ),
        op: (slotProps: any) => (
          <Space>
            <Link theme="primary" onClick={() => unEditUser(slotProps)}>
              修改
            </Link>
            <Link theme="danger" onClick={() => deleteClickOp(slotProps, false)}>
              {t('pages.detailCard.detail.form.delete')}
            </Link>
          </Space>
        ),
      }}
    </MyTable>
  </>
);

const unGetList = async () => {
  try {
    const res = await getList({
      pageNum: pagination.value.defaultCurrent,
      pageSize: pagination.value.defaultPageSize,
    });
    data.value = res.rows;
    pagination.value = {
      ...pagination.value,
      total: res.total,
    };
  } catch (e) {
    console.log(e);
  }
};

unGetList();

/** 添加对话框 */
const formObj = new formGroup();
const unAdd = () => {
  allChecked.value = [];
  formObj.show('添加角色', {}, '添加角色');
};
formObj.add<any>(
  '添加角色',
  '添加角色',
  {
    data: {
      // 默认值
      roleSort: 0,
      status: '0',
    },
  },
  async (body) => {
    body.data.menuIds = allChecked.value;
    await add(body.data);
    unGetList();
  },
  {
    roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
    roleKey: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
  },
);

// 角色详情 (修改)
const unEditUser = async (slotProps: any) => {
  try {
    const res = await getInfo(slotProps.row.roleId);
    const re = await roleMenuTreeselect(slotProps.row.roleId);
    allChecked.value = re.checkedKeys;
    formObj.show(
      '编辑角色',
      {
        ...res.data,
        menuIds: allChecked.value,
      },
      '编辑角色',
    );
  } catch (e) {
    console.error('获取角色详情失败:', e);
    MessagePlugin.error('获取角色详情失败');
  }
};

formObj.add<any>(
  '编辑角色',
  '编辑角色',
  {},
  async (body) => {
    body.data.menuIds = allChecked.value;
    await edit(body.data);
    unGetList();
  },
  {
    roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
    roleKey: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
  },
);

// 删除
const confirmVisible = ref(false);
const deleteId = ref([]);
const onConfirmDelete = () => {
  const ids = deleteId.value.join(',');
  Delete(ids).then(() => {
    confirmVisible.value = false;
    MessagePlugin.success('删除成功');
    unGetList();
  });
};

const deleteClickOp = (value: any, isSingle: boolean) => {
  if (isSingle && !value.length) {
    MessagePlugin.warning('请先勾选数据');
    return;
  }
  confirmVisible.value = true;
  deleteId.value = isSingle ? value : [value.row.roleId];
};

// 树区域
const tree = ref(null);
const expandAll = ref(false);
const checkStrictly = ref(false);
const allChecked = ref([]);
const menuOptions = ref([]);
// 查询菜单下拉树结构
const getMenuTreeselect = () => {
  menuTreeselect().then((response) => {
    menuOptions.value = response.data;
  });
};
getMenuTreeselect();

// 全选树反选树
const isAllSelectedComputed = computed({
  get: () => {
    if (!tree.value || allChecked.value.length === 0) return false;

    const allNodes = tree.value.getItems();
    const allCheckableValues = allNodes.filter((node) => node.checkable !== false).map((node) => node.value);

    return allCheckableValues.length > 0 && allCheckableValues.every((val) => allChecked.value.includes(val));
  },
  set: (value) => {
    // 当手动点击复选框时触发
    if (value) {
      selectAll();
    } else {
      clearAll();
    }
  },
});

// 全选
const selectAll = () => {
  if (!tree.value) return;

  const allNodes = tree.value.getItems();
  allChecked.value = allNodes.filter((node) => node.checkable !== false).map((node) => node.value);
};

// 清空选择
const clearAll = () => {
  allChecked.value = [];
};

// 反选/切换
const selectInvert = () => {
  if (isAllSelectedComputed.value) {
    selectAll();
  } else {
    clearAll();
  }
};

const onCancel = () => {
  if (deleteId.value.length < 2) {
    deleteId.value = [];
  }
};
</script>

<template>
  <div>
    <render />
    <!-- 对话框 -->
    <form-dialog-group :form-obj="formObj">
      <template #default="{ formData, item }">
        <template v-if="item == '添加角色' || item == '编辑角色'">
          <t-form-item label="角色名称" name="roleName">
            <t-input v-model="formData.roleName" placeholder="请输入角色名称" />
          </t-form-item>
          <t-form-item label="权限字符" name="roleKey">
            <t-input v-model="formData.roleKey" placeholder="请输入权限字符" />
          </t-form-item>
          <t-form-item label="角色顺序" name="roleSort">
            <t-input-number v-model="formData.roleSort" />
          </t-form-item>
          <t-form-item label="状态" name="status">
            <t-radio-group v-model="formData.status">
              <t-radio value="0">正常</t-radio>
              <t-radio value="1">停用</t-radio>
            </t-radio-group>
          </t-form-item>
          <t-form-item label="菜单权限" name="roleIds">
            <div>
              <div style="display: flex; gap: 24px">
                <t-checkbox v-model="expandAll">展开/折叠</t-checkbox>
                <t-checkbox v-model="isAllSelectedComputed" @change="selectInvert">全选/全不选</t-checkbox>
                <t-checkbox v-model="checkStrictly">严格模式</t-checkbox>
              </div>
              <!-- :check-strictly 父子关联 :expand-all 是否展开所有 -->
              <t-tree
                ref="tree"
                v-model="allChecked"
                :data="menuOptions"
                :expand-all="expandAll"
                :checkable="true"
                :check-strictly="checkStrictly"
                :keys="{ value: 'id' }"
                value-mode="all"
                hover
              />
            </div>
          </t-form-item>
          <t-form-item label="备注" name="remark">
            <t-textarea v-model="formData.remark" placeholder="请输入内容" />
          </t-form-item>
        </template>
      </template>
    </form-dialog-group>
    <t-dialog
      v-model:visible="confirmVisible"
      header="确认删除当前所选项目？"
      body="删除后，数据将被清空，且无法恢复"
      :on-cancel="onCancel"
      @confirm="onConfirmDelete"
    />
  </div>
</template>
